﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Net.Http;
using System.Text.RegularExpressions;
using System.Windows.Forms;

namespace _5
{
    public class Crawler
    {
        private const int MaxResult = 100;
        private const string PhoneNumberPattern = @"(13[0-9]|14[01456879]|15[0-35-9]|16[2567]|17[0-8]|18[0-9]|19[0-35-9])\d{8}";
        private const string HrefRegex = @"(href|HREF)[]*=[]*[""'][^""'#>]+[""']";
        private readonly Hashtable _urls = new Hashtable();
        private readonly HttpClient _httpClient;
        private BackgroundWorker _backgroundWorker;
        private Dictionary<string, string> Telephone { get; } = new Dictionary<string,string>();

        private Crawler()
        {
            var handler = new HttpClientHandler
            {
                AllowAutoRedirect = true,
                MaxAutomaticRedirections = 50,
                UseCookies = false,
            };
            _httpClient = new HttpClient(handler);
            _httpClient.BaseAddress = new Uri("https://cn.bing.com/search?q=");
            _httpClient.DefaultRequestHeaders.Add("user-agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36 Edg/130.0.0.0");
            _httpClient.DefaultRequestHeaders.Add("Cookie","_EDGE_V=1; MUID=3F7A4EAAF9C6675E0E1E5D78F8A06649; SRCHD=AF=NOFORM; SRCHUID=V=2&GUID=7D1EFB93A2694AD5926784B51665C7B4&dmnchg=1; MMCASM=ID=497A6FC0C5444BBA9F87466ECA0A0047; _TTSS_OUT=hist=WyJlbiIsInpoLUhhbnMiXQ==; _FP=hta=off; MSPTC=kS1dMJWrP1QJnhb89Y_qvCskvFjO4fHbSowgq-QSfOc; ANON=A=5A0BDE02AA224AD2D80FBF3CFFFFFFFF&E=1d3e&W=1; PPLState=1; KievRPSSecAuth=FABaBBRaTOJILtFsMkpLVWSG6AN6C/svRwNmAAAEgAAACBvUPFGmT8MuGASWsjGXlhW5/Mptk+avcUikO010MUZo8M7EOmWM5U7DHDUiUudLq9Bh1KPhP3GKXDAJ8KOIaMQ6LDiwCrr0BjM0i/RGWOLibrdrE0XN5QUH5ymQepu3UrcCHr7miOh1A7ztdVeInP5sFkP4TH+jlp0FbzQmyP7TkpL5IGfN3M3Ky4LdrXLj3AhG4F2Q3iut5V6z5gFxBtfrPazPPIG6ohtnxrczijxQbvAt+F0EBOWSBahuSDrAr2xv7W4zC9vUqC54vXzQIN32Egp8HUeuatD2MEyGtdx228nFa/GOdV2V9Q4rPVaIRQgbF320dq3USYKWv4v3ylzDTR6dwAb0exh0ZB5/FTqHqSm0URPd+1HAhFHa9ilJkLzoKr5PKIMD8wZV/3IVLWsMoqauF69V0/Qo21n7j2o25MAy4BxzJYtg9sXunksib1I5ze1bQg8l2RhdDRPlDKdn0gpXrJ7Bjqe8pJuUxhFIe/LVJdasmvpmnnJm7OOc2IKT8gs2MonTOS34HWxOxmgZM2xss4nhMHC9oWAUTbLEx1gQiwaC7vSszeLpevDpPZpfALupxgM0HATUeeEfM9xcvxmh4uMHYuQAi2Ck9tPI8KYob/t8MOi7fP5KNWDCkkJ0o4MmHxxgX5qTsE1bEPv7949IPlzLTZL7qIIJb/A1dURk0KOVEn3O87xr6h/KdoBKwSsuic7VYg+sAKkH6xv2visRirflMFkOaFOnmcYJQKHMR8WXW9pwtJGuHBK3RJEXLsGB7yNJpAUJtlVzJxDaC8ClIKAS7wWXOwS6y1yg28+AXTHbQIThaqqg95PbRQyvdo+7wXWfxNA+pSvw7WVBP6MyXMJQK2hcBql3p5fwUn4pK67mi39n1HpG0cgwMUc5SWX25ckG0J2RpaAeuUZ/x/jdvxqJKZGah4Q+Dab81Z1VaEHAiNxqD6yIwqs23P6MliW9BzXZ/8PAhm0UK9Z93fIjof5uF1u+VZLzFDnOOP4xATJOwLdyoaZwYUz08LEwmk14fYmzqUvRpF9QZknpaLHNrjphKoMzHg3H3b5KTNJCkeZAK7/mItCR1Sr7Jpc2Unh9wXN/xxloreJYsyaz6FHrrNmtncO8Tvtjx7s42og+Hd/yHn2qbyL7dlMoABSd6SjUj8iF/tWocBVf461qthCWZ8qiy2ipb6zJ6L6agH1oPpRmvh5tlHSf3CdMPka16kML6KqbbIr5NUgzGrQi0PiIwU4U0AIP1DgL9S3D4IDwiYzxu2QoJvqjhJsqjZ1Wyh/52pVd/LGd7RA2lhocOxfolxuUe+5yTnM4H+CetyatVrDjCyKFVWt1OAL73q56LaLEOasFOCNqC2Pju4pvq2WiHqYgzPd5N5IjYtoueFP3TLeSUFyYv3oHMiUwtmSwFAAoPa0eQMYcmGBbrPnORezCH+5V1A==; TRBDG=FIMPR=1; _tarLang=default=zh-Hans&newFeature=tonetranslation; _UR=QS=0&TQS=0&Pn=0; _TTSS_IN=hist=WyJpdCIsImphIiwiZW4iLCJhdXRvLWRldGVjdCJd&isADRU=0; _EDGE_S=SID=01126064B6AE637430F67544B7E462DC; WLS=C=9ff47c19eaa66221&N=%e6%98%8c%e6%89%8d; SRCHUSR=DOB=20240420&T=1729579565000; _Rwho=u=d&ts=2024-10-22; SNRHOP=I=&TS=; _U=1cRKMiphWMO67LUmW72MwfMtRCzaTWtmSJUlRN6Aa905CbW3oPG7g3Ci6-h5mOCgkCa2y364dW8jJAYSPKGvMhpNQlUihPc1q5csNVtu45W_1bwdEqR5fzI2ZOsR5ubvm7AUXWK_C2rT6PqojjNYEoYbvrxDRY5uJXyHGD0ZILT8gQFSv-1OyTobGBL0EU3c8KBrDs-5Z_zPCQZ-JaZf0gp4Jngqz9vxd9MoZaDt4JiI; _HPVN=CS=eyJQbiI6eyJDbiI6MTEsIlN0IjowLCJRcyI6MCwiUHJvZCI6IlAifSwiU2MiOnsiQ24iOjExLCJTdCI6MCwiUXMiOjAsIlByb2QiOiJIIn0sIlF6Ijp7IkNuIjoxMSwiU3QiOjAsIlFzIjowLCJQcm9kIjoiVCJ9LCJBcCI6dHJ1ZSwiTXV0ZSI6dHJ1ZSwiTGFkIjoiMjAyNC0xMC0yMlQwMDowMDowMFoiLCJJb3RkIjowLCJHd2IiOjAsIlRucyI6MCwiRGZ0IjpudWxsLCJNdnMiOjAsIkZsdCI6MCwiSW1wIjoyMywiVG9ibiI6MH0=; ipv6=hit=1729585590624&t=4; GC=8HZbWbQBHWuVNJYe6lVxOZEb3f0X9FvyT54d6LH9H2X66WMgJTC8SzaC0uQmIWl6YSRZYlBMAvRHKiXqIqTS8Q; _RwBf=mta=0&rc=4044&rb=4044&gb=0&rg=17915&pc=4041&mtu=0&rbb=0.0&g=0&cid=&clo=0&v=15&l=2024-10-22T07:00:00.0000000Z&lft=0001-01-01T00:00:00.0000000&aof=0&o=16&p=bingcopilotwaitlist&c=MY00IA&t=1888&s=2023-03-12T09:41:49.9354672+00:00&ts=2024-10-22T07:32:39.7507703+00:00&rwred=0&wls=0&wlb=0&lka=0&lkt=0&aad=0&TH=&e=a2ebsn-viTXOuZxAqq9-wBfO_WGaujdDftkG9-QWCOMIQfkzH_ddpikBmtlcykLAu7a0GRN8QUKETogcQ7LYA4Qtq-OtpROP6L5pPDATkNY&A=&ccp=2&wle=1&ard=0001-01-01T00:00:00.0000000&rwdbt=1724361947&rwflt=1728846097&cpt=0&rwaul2=0; _SS=SID=01126064B6AE637430F67544B7E462DC&PC=MOZI&R=4044&RB=4044&GB=0&RG=17915&RP=4041; dsc=order=BingPages; SRCHHPGUSR=SRCHLANG=zh-Hans&PV=15.0.0&BZA=0&BRW=NOTP&BRH=M&CW=759&CH=731&SCW=744&SCH=2318&DPR=1.3&UTC=480&DM=0&EXLTT=31&HV=1729582358&PRVCW=759&PRVCH=731&PR=1.5&IG=6F2380D5E8D84610A8369CD9B82D629F&WEBTHEME=0&THEME=0; USRLOC=HS=1&ELOC=LAT=30.535661697387695|LON=114.35740661621094|N=%E6%AD%A6%E6%98%8C%E5%8C%BA%EF%BC%8C%E6%B9%96%E5%8C%97%E7%9C%81|ELT=2|&DLOC=LAT=30.53798679530527|LON=114.35187196021276|A=70|N=%e6%ad%a6%e6%b1%89%e5%b8%82%e6%ad%a6%e6%98%8c%e5%8c%ba|C=|S=|TS=241022073240|ETS=241022074240|&CLOC=LAT=30.541183722522145|LON=114.34639401160888|A=733.4464586120832|TS=241022064608|SRC=W&BID=MjQxMDIyMTQ0NjA0Xzk1OGRjZmFjNzY0YjU5NTRiNjNlYzcxMGM3OTY4YmU0ZTNkNGJkNGZhZjM1NTBkOWFiZDlmMGRhZGIxOWU4Nzk=");
        }

        public Crawler(string key):this()
        {
            var url = $"https://cn.bing.com/search?q={key}";
            if (_urls[url] == null) _urls[url] = false;
        }

        public async void Crawl(object sender, DoWorkEventArgs e)
        {
            _backgroundWorker = sender as BackgroundWorker;
            while (true)
            {
                try
                {
                    var current = string.Empty;
                    foreach (string url in _urls.Keys)
                    {
                        if ((bool)_urls[url]) continue;
                        current = url;
                    }

                    if (current == string.Empty || Telephone.Count >= MaxResult)
                    {
                        MessageBox.Show(@"爬取完成");
                        break;
                    }
                    _urls[current] = true;
                    var html = await _httpClient.GetAsync(current).Result.Content.ReadAsStringAsync();
                    Parse(html, current);
                }
                catch (Exception exception)
                {
                    MessageBox.Show(exception.Message);
                }
            }
        }

        private void Parse(string htmlContent, string url)
        {
            var matches = new Regex(HrefRegex).Matches(htmlContent);
            foreach (Match match in matches)
            {
                var strRef = match.Value.Substring(match.Value.IndexOf('=') + 1).Trim('"', '\"', '#', '>');
                if (strRef.Length == 0) continue;
                if (_urls[strRef] == null) _urls[strRef] = false;
            }

            matches = new Regex(PhoneNumberPattern).Matches(htmlContent);
            foreach (Match match in matches)
            {
                if (Telephone.ContainsKey(match.Value) && Telephone[match.Value] != null)
                {
                    continue;
                }
                Telephone[match.Value] = url;
                _backgroundWorker.ReportProgress(Telephone.Count, (match.Value, url));
            }
        }
    }
}